#pragma once

#include "Log.hpp"
#include <jsoncpp/json/json.h>
#include <exception>
#include <sstream>
#include <memory>

namespace Util
{
    class json
    {
    public:

        /**
         * @brief 将JSON对象序列化为字符串。
         * 
         * 此函数接收一个Json::Value对象，并将其序列化为字符串表示形式。
         * 
         * @param root 要序列化的Json::Value对象。
         * @param outbuffer 指向std::string的指针，用于保存序列化后的JSON字符串。
         * 
         * @return 如果序列化成功，则返回true；否则返回false。
         * 
         * @details 该函数使用Json::StreamWriter类将JSON数据写入输出流中。
         *          在序列化过程中，如果捕获到任何std::exception，则会将其记录为致命错误。
         */
        static bool serialize(const Json::Value &root, std::string* outbuffer)
        {
            Json::StreamWriterBuilder swb;
            std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());

            std::stringstream out;
            try
            {
                sw->write(root, &out);
            }
            catch (std::exception &e)
            {
                LOG(FATAL, e.what());
                return false;
            }

            *outbuffer = std::move(out.str());
            return true;
        }


        /**
         * @brief 反序列化JSON字符串为Json::Value对象。
         * 
         * @param out 指向Json::Value的指针，保存反序列化后的JSON对象。
         * @param str 要反序列化的JSON字符串。
         * 
         * @return 反序列化成功返回true，否则返回false。
         * 
         * @details 使用Json::CharReader将JSON字符串解析为Json::Value对象。
         *          解析失败将返回false，并记录解析错误信息。
         */
        static bool deserialize(Json::Value *out, const std::string &str)
        {
            Json::CharReaderBuilder crb;
            std::unique_ptr<Json::CharReader> cr(crb.newCharReader());

            std::string erro;
            if (!cr->parse(str.c_str(), str.c_str() + str.size(), out, &erro))
            {
                LOG(FATAL, erro.c_str());
                return false;
            } 

            return true;
        }
    };
}